#include "Inc/server.h"
#include <QDebug>

Server::Server(QObject *parent)
    : QObject{parent}, port(PORT), tcp_clients_count(0), server_running(false)
{
    server = new QTcpServer(this);
    qDebug() << "server init" << Qt::endl;
    connect(server, &QTcpServer::newConnection, this, &Server::onNewConnection);
    if (!server->listen(QHostAddress::Any, PORT))
    {
        qDebug() << "Server could not start!";
        server_running = false;
    }
    else
    {
        qDebug() << "Server started on port" << PORT;
        server_running = true;
        // 获取本机IP地址(只获取eth0:host_ip, eth1:gateway_ip)
        foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces())
        {
            const auto entries = interface.addressEntries();
            if (interface.name() == "eth0" && !entries.isEmpty())
            {
                host_ip = entries.first().ip().toString();
            }
            else if (interface.name() == "eth1" && !entries.isEmpty())
            {
                gateway_ip = entries.first().ip().toString();
            }
        }
    }
}

Server::~Server()
{
    if (server->isListening())
    {
        server->close();
    }
    // 释放QList中的Device对象
    qDeleteAll(device_list);
    device_list.clear();
    delete server;
}

void Server::onNewConnection()
{
    QTcpSocket *clientSocket = server->nextPendingConnection();
    clientSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
    if (clientSocket)
    {
        clients.insert(clientSocket, 0xFF);
        connect(clientSocket, &QTcpSocket::readyRead, this, &Server::onReadyRead);
        connect(clientSocket, &QTcpSocket::disconnected, this, &Server::onDisconnected);

        tcp_clients_count = clients.size();
        qDebug() << "New client connected:" << clientSocket->peerAddress().toString();
        emit clientsChanged();
    }
}

void Server::onReadyRead()
{
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());
    if (clientSocket)
    {
        QByteArray data = clientSocket->readAll();
        QByteArray response;
        Device *device;
        quint8 device_id;
        quint32 record_index;
        quint16 freq;
        QString hexData;
        for (int i = 0; i < data.size(); ++i)
        {
            hexData += QString("%1 ").arg(static_cast<unsigned char>(data[i]), 2, 16, QLatin1Char('0')).toUpper();
        }
        qDebug() << "Received data from" << clientSocket->peerAddress().toString() << ":" << hexData.trimmed();
        switch (data[0])
        {
        case 0x00: // MCU初始化
            // data[1] 为设备id
            // 先判断data[1]是否存在，避免下标越界
            if (data.size() > 1)
            {
                device_id = data[1];
                if (device_map.contains(device_id))
                {
                    // ID重复
                    if (device_map[device_id]->getDeviceStatus() == Types::DISCONNECTED || device_map[device_id]->getDeviceStatus() == Types::TIMEOUT)
                    {
                        clients[clientSocket] = device_id;
                        device_map[device_id]->setDeviceStatus(Types::IDLE);
                        device_map[device_id]->socket_ins = clientSocket;
                        device_map[device_id]->setLastUpdate();
                        device_map[device_id]->setIpAddress(clientSocket->peerAddress().toString());
                        emit devicesChanged();
                        qDebug() << "Device reconnected with ID:" << device_id;
                    }
                    else
                    {
                        qDebug() << "Device ID already exists:" << device_id;
                    }
                    return;
                }
                quint8 existing_id = clients.value(clientSocket, 0xFF);
                clients[clientSocket] = device_id;
                if (existing_id != 0xFF)
                {
                    // 设备已经存在异常
                    qDebug() << "Device already initialized.";
                    return;
                }

                // 创建新的Device对象
                Device *newDevice = new Device(this, device_id, clientSocket, clientSocket->peerAddress().toString());
                device_list.append(newDevice);
                device_map[device_id] = newDevice;
                emit devicesChanged(); // Notify that devices have changed
                qDebug() << "Device initialized with ID:" << device_id;
            }
            else
            {
                qDebug() << "Invalid initialization data received.";
            }
            break;
        case 0x01:
            /*
            data[1], data[2] uint16 电池电压值
            data[3] ~ data[10] double 阻抗虚部
            data[11] ~ data[18] double 阻抗实部
            */
            // 先判断长度
            if (data.size() < 19)
            {
                qDebug() << "Invalid data length for impedance measurement.";
                return;
            }
            device_id = clients.value(clientSocket, 0xFF);
            if (device_id != 0xFF && device_map.contains(device_id))
            {
                quint16 volt = (static_cast<quint16>(data[1]) << 8) | static_cast<quint16>(data[2]);
                // 浮点数导入
                double image = 0.0;
                double real = 0.0;
                memcpy(&image, data.data() + 3, sizeof(double));
                memcpy(&real, data.data() + 11, sizeof(double));
                device_map[device_id]->onResultReceived(volt, real, image);
                qDebug() << "Impedance measurement received for device ID:" << device_id
                         << "Voltage:" << volt
                         << "Real:" << real
                         << "Imaginary:" << image;
            }
            else
            {
                qDebug() << "Device ID not found for impedance measurement.";
            }
            break;
        case 0x02: // 电压数据
            if (data.size() < 3)
            {
                qDebug() << "Invalid data length for voltage measurement.";
                return;
            }
            device_id = clients.value(clientSocket, 0xFF);
            if (device_id != 0xFF && device_map.contains(device_id))
            {
                quint16 volt1 = (static_cast<quint16>(data[1]) << 8) | static_cast<quint16>(data[2]);
                device_map[device_id]->onVoltageReceived(volt1);
                qDebug() << "Voltage measurement received for device ID:" << device_id << "Voltage:" << volt1;
            }
            else
            {
                qDebug() << "Device ID not found for voltage measurement.";
            }
            break;
        case 0x03: // MCU任务应答
            device_id = clients.value(clientSocket, 0xFF);
            if (device_id != 0xFF && device_map.contains(device_id))
            {
                device_map[device_id]->onMeasureAck();
            }
            else
            {
                qDebug() << "Device ID not found for task acknowledgment.";
            }
            break;
        case 0x04: // MCU停止应答
            device_id = clients.value(clientSocket, 0xFF);
            if (device_id != 0xFF && device_map.contains(device_id))
            {
                device_map[device_id]->onStopAck();
                qDebug() << "Stop acknowledged for device ID:" << device_id;
            }
            else
            {
                qDebug() << "Device ID not found for stop acknowledgment.";
            }
            break;
        case 0x40: // PC上位机注册
            if (!pcs.contains(clientSocket))
            {
                pcs.append(clientSocket);
            }
            // 向PC发送数据

            response.append(0x60); // 初始化数据
            // 先写入设备列表
            response.append(static_cast<char>(device_map.size())); // 设备数量
            // ID+状态
            for (auto it = device_map.constBegin(); it != device_map.constEnd(); ++it)
            {
                response.append(static_cast<char>(it.key()));                      // 设备ID
                response.append(static_cast<char>(it.value()->getDeviceStatus())); // 设备状态
                const auto &records = it.value()->getResults();

                quint32 record_count = static_cast<quint32>(records.size());
                response.append(reinterpret_cast<const char *>(&record_count), sizeof(record_count)); // 记录数量(quint32)
                for (const auto &record : records)
                {
                    response.append(static_cast<char>(record->getTaskType()));       // 任务类型
                    response.append(static_cast<char>(record->getDrivingCurrent())); // 采样电流档位
                    qint64 timestamp = record->getCreateTime().toSecsSinceEpoch();
                    response.append(reinterpret_cast<const char *>(&timestamp), sizeof(timestamp)); // 采样时间
                    response.append(static_cast<char>(record->getPoints().size()));                 // 采样点数
                }
                const auto &tasks = it.value()->getTasks();

                response.append(static_cast<char>(tasks.size())); // 任务数量
                for (const auto &task : tasks)
                {
                    quint64 task_id = task->getId();
                    response.append(reinterpret_cast<const char *>(&task_id), sizeof(task_id)); // 任务ID
                    response.append(static_cast<char>(task->isEnabled()));                      // 任务是否启用
                    response.append(static_cast<char>(task->getPriority()));                    // 任务优先级
                    response.append(static_cast<char>(task->isRepeat()));                       // 是否重复
                    response.append(static_cast<char>(task->getTaskType()));                    // 任务类型
                    response.append(static_cast<char>(task->getCurrent()));                     // 采样电流档位
                    quint16 freq = task->getFreq();
                    response.append(reinterpret_cast<const char *>(&freq), sizeof(freq)); // 采样频率
                    quint64 interval = task->getInterval();
                    response.append(reinterpret_cast<const char *>(&interval), sizeof(interval)); // 任务间隔时间
                }
            }
            clientSocket->write(response);
            qDebug() << "PC registered.";

            break;
        case 0x41:
            // 开始测量 1byte(设备编号)+1byte(测量模式)+1byte(采样电流档位)+1byte(单点采样频率)
            if (data.size() < 5)
            {
                qDebug() << "Invalid data length for measurement request.";
                return;
            }
            device_id = data[1];
            device = device_map.value(device_id, nullptr);
            if (device || device->getDeviceStatus() == Types::IDLE)
            {
                switch (data[2])
                {
                case Types::GET_EIS:
                    device->newEIS(static_cast<Types::DrivingCurrent>(static_cast<quint8>(data[3])));
                    break;
                case Types::GET_SINGLE:
                    // 判断频率范围是否合法
                    freq = *reinterpret_cast<const quint16 *>(data.data() + 4);
                    if (freq < 1 || freq > 2000) // 假设频率范围是1Hz到1000Hz
                    {
                        qDebug() << "Invalid frequency for single measurement:" << freq;
                        return;
                    }
                    device->newSingle(static_cast<Types::DrivingCurrent>(static_cast<quint8>(data[3])), freq);
                    break;
                default:
                    qDebug() << "Unknown measurement mode:" << static_cast<int>(data[2]);
                    return;
                }

                break;
            case 0x42: // 请求设备测量结果 1(设备编号)+4（记录编号）
                // 向client发送设备测量结果 1byte(设备编号)+4byte(记录下标)+1byte(采样点数n)+n*[2byte(频率)+4byte(电压)+8byte(虚部)+8byte(实部)]
                if (data.size() < 5)
                {
                    qDebug() << "Invalid data length for measurement results request.";
                    return;
                }
                device_id = data[1];
                record_index = *reinterpret_cast<const quint32 *>(data.data() + 2);
                response.append(0x67);
                if (device_map.contains(device_id))
                {
                    response.append(static_cast<char>(device_id));                                        // 设备ID
                    response.append(reinterpret_cast<const char *>(&record_index), sizeof(record_index)); // 记录下标
                    const auto &results = device_map[device_id]->getResults()[record_index];
                    const auto &points = results->getPoints();
                    response.append(static_cast<char>(points.size())); // 采样点数
                    for (const auto &point : points)
                    {
                        quint16 freq = point->getFreq();
                        response.append(reinterpret_cast<const char *>(&freq), sizeof(freq)); // 频率
                        // 浮点数填充
                        float voltage = point->getVoltage();
                        response.append(reinterpret_cast<const char *>(&voltage), sizeof(voltage)); // 电压
                        double imag = point->getImag();
                        response.append(reinterpret_cast<const char *>(&imag), sizeof(imag)); // 虚部
                        double real = point->getReal();
                        response.append(reinterpret_cast<const char *>(&real), sizeof(real)); // 实部
                    }
                    if (points.isEmpty())
                    {
                        response.append(static_cast<char>(0)); // 如果没有采样点，发送0
                    }

                    qDebug() << "Measurement results sent for device ID:" << device_id
                             << "Record index:" << static_cast<int>(record_index)
                             << "Points count:" << points.size();
                }
                else
                {
                    response.append(static_cast<char>(0)); // 设备ID不存在
                }
                clientSocket->write(response);
                qDebug() << "Sent measurement results for device ID:" << device_id
                         << "Record index:" << static_cast<int>(record_index);
                break;
            case 0x43: // 写入任务 1(设备编号)+8(任务ID)+1(是否启用)+1(优先级)+1(是否重复)+1(任务类型)+1(采样电流档位)+2(采样频率)+8(任务间隔时间)
            {
                if (data.size() < 20)
                {
                    qDebug() << "Invalid data length for task write request.";
                    return;
                }
                device_id = data[1];
                if (!device_map.contains(device_id))
                {
                    qDebug() << "Device ID not found for task write request:" << device_id;
                    return;
                }
                auto task_id = *reinterpret_cast<const quint64 *>(data.data() + 2);
                bool enabled = static_cast<bool>(data[10]);
                quint8 priority = data[11];
                bool repeat = static_cast<bool>(data[12]);
                auto task_type = static_cast<Types::TaskType>(static_cast<quint8>(data[13]));
                auto driving_current = static_cast<Types::DrivingCurrent>(static_cast<quint8>(data[14]));
                quint16 freq = *reinterpret_cast<const quint16 *>(data.data() + 15);
                quint64 interval = *reinterpret_cast<const quint64 *>(data.data() + 17);

                // 检查频率范围
                if (task_type==Types::GET_SINGLE && (freq < 1 || freq > 2000)) // 假设频率范围是1Hz到2000Hz
                {
                    qDebug() << "Invalid frequency for task write request:" << freq;
                    return;
                }
                
                Task *task = new Task();
                task->setEnabled(enabled);
                task->setPriority(priority);
                task->setRepeat(repeat);
                task->setTaskType(task_type);
                task->setCurrent(driving_current);
                task->setFreq(freq);
                task->setInterval(interval);
                device_map[device_id]->setTask(task_id, task);
                qDebug() << "Task written for device ID:" << device_id;}
                break;
            default:
                qDebug() << "Unknown command received:" << data[0];
                break;
            }
            // Process the data as needed
        }
    }
}

void Server::onDisconnected()
{
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());
    if (clientSocket)
    {
        qDebug() << "Client disconnected:" << clientSocket->peerAddress().toString();
        quint8 device_id = clients.value(clientSocket, 0xFF);
        if (device_id != 0xFF)
        {
            device_map[device_id]->socket_ins = nullptr;
            device_map[device_id]->setDeviceStatus(Types::DISCONNECTED);
            device_map[device_id]->setLastUpdate();
            emit devicesChanged(); // Notify that devices have changed
            qDebug() << "Device status updated to DISCONNECTED for ID:" << device_id;
        }
        else
        {
            if (pcs.contains(clientSocket))
            {
                pcs.removeAll(clientSocket);
                qDebug() << "PC disconnected:" << clientSocket->peerAddress().toString();
            }
        }
        clients.remove(clientSocket);
        clientSocket->deleteLater();
        tcp_clients_count = clients.size();
        emit clientsChanged();
    }
}

void Server::newMeasure(quint8 deviceId)
{
    device_map[deviceId]->newEIS(Types::AMPL_1A);
}

void Server::sendToPCs(const QByteArray &data)
{
    for (QList<QTcpSocket *>::iterator it = pcs.begin(); it != pcs.end(); ++it)
    {
        QTcpSocket *pc = *it;
        if (pc && pc->state() == QAbstractSocket::ConnectedState)
        {
            pc->write(data);
        }
    }
}
